package com.dick.base.util;

import fr.opensagres.poi.xwpf.converter.xhtml.Base64EmbedImgManager;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.web.util.HtmlUtils;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Base64;

/**
 * office文件转换工具
 */
public class OfficeConvertUtil {

    /**
     * 将.doc文件转换为html用于网页预览
     * @param inputStream
     * @return
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws TransformerException
     */
    public static String word2003ToHtml(InputStream inputStream) throws IOException, ParserConfigurationException, TransformerException {
        HWPFDocument wordDocument = new HWPFDocument(inputStream);
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
        );

        wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> {
            //带图片的word，则将图片转为base64编码，保存在一个页面中
            String base64Img = Base64.getEncoder().encodeToString(content);
            StringBuilder sb = new StringBuilder(base64Img.length() + "data:;base64,".length())
                    .append("data:;base64,")
                    .append(base64Img);
            return sb.toString();
        });

        // 解析word文档
        wordToHtmlConverter.processDocument(wordDocument);
        Document htmlDocument = wordToHtmlConverter.getDocument();

        // 生成html文件地址
        ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024*512);

        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(outStream);

        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer serializer = factory.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);
        outStream.close();
        return outStream.toString("utf-8");
    }

    /**
     * 将.docx文件转换为html用于网页预览
     * @param inputStream
     * @return
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws TransformerException
     */
    public static String word2007ToHtml(InputStream inputStream) throws IOException {
        //加载word文档生成 XWPFDocument对象
        XWPFDocument document = new XWPFDocument(inputStream);

        //带图片的word，则将图片转为base64编码，保存在一个页面中
        XHTMLOptions options = XHTMLOptions.create().indent(4).setImageManager(new Base64EmbedImgManager());

        //将 XWPFDocument转换成XHTML
        ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024*512);
        XHTMLConverter.getInstance().convert(document, outStream, options);
        outStream.close();

        return outStream.toString("utf-8") + "<style>table {border-collapse: collapse;}table p{white-space: normal !important;}</style>";
    }

    /**
     * 将html文件转换为word2003文件
     * @param html
     * @return
     */
    public static byte[] htmlToWord2003(String html) throws IOException {
        html = HtmlUtils.htmlUnescape(html);
        POIFSFileSystem poifsFileSystem = new POIFSFileSystem();
        DocumentEntry documentEntry = poifsFileSystem.createDocument(new ByteArrayInputStream(html.getBytes(Charset.forName("utf-8"))), "WordDocument");
        ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024*512);
        poifsFileSystem.writeFilesystem(outStream);
        outStream.close();
        return outStream.toByteArray();
    }
}
